package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.HotArticleService;

import com.heima.common.redis.CacheService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.vos.ApArticleVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class HotArticleServiceImpl implements HotArticleService {

    @Autowired
    private ApArticleMapper apArticleMapper;
    @Autowired
    private CacheService cacheService;

    @Override
    public void computeHotArticle() {
        //1.查询前5天的文章
        Date fiveDaysAgo = new Date(System.currentTimeMillis() - (1000L * 60 * 60 * 24 * 5));
        LambdaQueryWrapper<ApArticle> wrapper = Wrappers.<ApArticle>lambdaQuery().ge(ApArticle::getPublishTime, fiveDaysAgo);
        List<ApArticle> apArticles = apArticleMapper.selectList(wrapper);

        if(apArticles!=null&&apArticles.size()>0){
            //2.给文章算分
            List<ApArticleVo> apArticleVos = computeScore(apArticles);

            //3.针对每个频道进行文章的分数排名 --前30名存入redis
            //3.1拿到所有频道
            List<Integer> channelIds = apArticles.stream().map(ApArticle::getChannelId).distinct().collect(Collectors.toList());
            //3.2按频道进行分组统计
            for (Integer channelId : channelIds) {
                List<ApArticleVo> articleVosInSameChannel = apArticleVos.stream().filter(vo -> vo.getChannelId().equals(channelId)).collect(Collectors.toList());
                List<ApArticleVo> top30InSameChannel = articleVosInSameChannel.stream().sorted(new Comparator<ApArticleVo>() {
                    @Override
                    public int compare(ApArticleVo o1, ApArticleVo o2) {
                        return o2.getScore() - o1.getScore();
                    }
                }).limit(30).collect(Collectors.toList());
                cacheService.set("hot_article_"+channelId, JSON.toJSONString(top30InSameChannel));
            }

            //4.针对推荐进行文章的分数排名 --前30名存入redis
            List<ApArticleVo> top30 = apArticleVos.stream().sorted(new Comparator<ApArticleVo>() {
                @Override
                public int compare(ApArticleVo o1, ApArticleVo o2) {
                    return o2.getScore() - o1.getScore();
                }
            }).limit(30).collect(Collectors.toList());
            cacheService.set("hot_article__all__", JSON.toJSONString(top30));
        }
    }

    //给文章算分
    private List<ApArticleVo> computeScore(List<ApArticle> apArticles) {
        List<ApArticleVo> apArticleVos = new ArrayList<>();
        if (apArticles != null && apArticles.size() > 0) {
            for (ApArticle apArticle : apArticles) {
                int score = 0;
                Integer views = apArticle.getViews();
                if (views != null &&  views > 0 ) {
                    score += views;
                }
                Integer likes = apArticle.getLikes();
                if (likes != null &&  likes > 0 ) {
                    score += likes * 3;
                }
                Integer comment = apArticle.getComment();
                if (comment != null &&  comment > 0 ) {
                    score += comment * 5;
                }
                Integer collection = apArticle.getCollection();
                if (collection != null &&  collection > 0 ) {
                    score += collection * 8;
                }
                ApArticleVo apArticleVo = new ApArticleVo();
                BeanUtils.copyProperties(apArticle,apArticleVo);
                apArticleVo.setScore(score);
                apArticleVos.add(apArticleVo);
            }
            return apArticleVos;

        } else {
            return null;
        }

    }
}
